package com.atguigu.bookcity.controller;

import com.atguigu.bookcity.entity.User;
import com.atguigu.bookcity.entity.vo.RegisterVo;
import com.atguigu.bookcity.entity.vo.UserInfoVo;
import com.atguigu.bookcity.entity.vo.UserVo;
import com.atguigu.bookcity.exception.BookCityException;
import com.atguigu.bookcity.mapper.UserMapper;
import com.atguigu.bookcity.service.UserService;
import com.atguigu.bookcity.utils.RedisUtil;
import com.atguigu.bookcity.vo.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zsc
 * @since 2021-03-20
 */
@CrossOrigin
@RestController
@Api(tags = {"用户管理"})
@RequestMapping("/bookcity/user")
public class UserController {
    @Resource
    private UserService userService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisUtil redisUtil;

    @PostMapping("/login")
    public CommonResult logIn(String name, String password) {
        return userService.login(name, password);
    }

    @PostMapping("/register")
    @ResponseBody
    public CommonResult register(@RequestBody RegisterVo vo) {
        return userService.register(vo);
    }

    @PostMapping("/logout")
    @ApiOperation(value = "用户注销")
    public CommonResult Logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();

        return CommonResult.ok();
    }

    @ApiOperation(
            value = "管理员注册,注册后台角色",
            notes = "admin权限",
            produces = "application/json")
    @RequiresRoles("admin")
    @PostMapping("/admin/register")
    public CommonResult adminRegister(@RequestBody RegisterVo vo,
                                      @RequestParam String role) {
        return userService.adminRegister(vo, role);
    }

    @ApiOperation(
            value = "本系统所有用户的角色信息",
            notes = "admin或manager权限使用此接口",
            produces = "application/json")
    @GetMapping("/getUsersInfo")
    @RequiresRoles(
            value = {"admin", "manager"},
            logical = Logical.OR)
    public CommonResult getUsersInfo() {
        List<UserInfoVo> usersInfo = userMapper.getUserInfo();
        return CommonResult.ok().data("usersInfo", usersInfo);
    }

    @ApiOperation(
            value = "获取本系统用户的信息",
            produces = "application/json")
    @GetMapping("/getUserInfo")
    public CommonResult getUsersInfoById() {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        return CommonResult.ok()
                .data("username", user.getUsername())
                .data("role",user.getRole());
    }


    @ApiOperation(
            value = "重置用户角色",
            notes = "admin权限使用此接口",
            produces = "application/json")
    @PostMapping("/modifyUserRole")
    @RequiresRoles("admin")
    public CommonResult modifyUserRoleById(@RequestParam String userId,
                                           @RequestParam String newRole) {
        userService.modifyUserRoleById(userId, newRole);
        return CommonResult.ok();
    }

    private final String prifix = "shiro:cache:com.atguigu.bookcity.realm.UserRealm.authenticationCache:";

    @ApiOperation(
            value = "用户修改自己账户",
            notes = "登录使用",
            produces = "application/json")
    @PostMapping("/modifyPassword")
    public CommonResult modifyPassword(@RequestBody UserVo vo) {
        boolean isOk = userService.modifyPassword(vo);
        if (!isOk)
            throw new BookCityException(201, "密码修改失败");
        redisUtil.del(prifix + vo.getUsername());
        return CommonResult.ok();
    }


    @ApiOperation(
            value = "重置用户密码",
            notes = "admin权限使用此接口",
            produces = "application/json")
    @RequiresRoles("admin")
    @PostMapping("/resetUserPassword")
    public CommonResult resetPassword(String username) {
        userService.resetPassword(username);
        redisUtil.del(prifix + username);
        return CommonResult.ok();
    }
}

